<!--
* @Description: Tabs组件
* @Author: Rulyc
* @Operating:
-->
<template>
  <div class="lc-tabs">
    <!-- 导航部分 -->
    <div class="lc-tabs-nav" ref="container">
      <div class="lc-tabs-nav-item"
           v-for="(title, index) in titles"
           :key="`tab-${index}`"
           :class="{selected: title === selected}"
           :ref="el => { if(title===selected) selectedItem =el }"
           @click="selectClick(title)"
      >
        {{ title }}
      </div>
      <!--  下划线    -->
      <div class="lc-tabs-nav-indicator" ref="indicator"></div>
    </div>
    <div class="lc-tabs-content">
      <component :is="current" :key="current.props.title" />
    </div>
  </div>
</template>

<script lang="ts">
import LcTab from './Tab.vue'
import { computed, ref, onMounted, watchEffect } from 'vue'
export default {
  name: "LcTabs",
  components: {
    LcTab
  },
  // 定义属性
  props: {
    selected: {
      type: String
    }
  },
  setup(props, context){
    /** 计算div横线的位置 */
    const selectedItem = ref<HTMLDivElement>(null) // 直接定义一个被选中的Item
    const indicator = ref<HTMLDivElement>(null) // 定义一个下划线div
    const container = ref<HTMLDivElement>(null) // 导航栏容器
    onMounted(()=>{
      watchEffect(()=>{
        // 获取选中Item的宽度
        const { width } = selectedItem.value.getBoundingClientRect()
        indicator.value.style.width = width + 'px'
        const { left: containerLeft } = container.value.getBoundingClientRect()
        const { left: selectedItemLeft } = selectedItem.value.getBoundingClientRect()
        const left = selectedItemLeft - containerLeft
        indicator.value.style.left = left + 'px'
      }, {
        flush: 'post'
      }) // flush: 'post'在后面执行，正式版本的改动
    })

    // 获取Tabs下的所有一级子标签
    const defaults = context.slots.default()
    console.log(defaults)
    // 循环遍历defaults, 如果子标签不是Tab,抛出异常，代码更加严谨
    defaults.forEach((tag)=>{
      if(tag.type !== LcTab) {
        throw new Error('Tabs 子标签必须是 Tab')
      }
    })
    // 获取title数组
    const titles = defaults.map((tag)=>{
      return tag.props.title
    })
    // 通过计算属性时实获取当前选中的导航栏对应的内容
    const current = computed(()=>{
      return defaults.find(tag=> tag.props.title === props.selected)
    })
    /** 点击导航栏 */
    const selectClick = (title: string)=>{
      context.emit('update:selected', title)
    }
    return {
      defaults,
      titles,
      selectClick,
      current,
      selectedItem,
      indicator,
      container
    }
  }
}
</script>

<style lang="scss">
  $blue: #40a9ff;
  $color: #333;
  $border-color: #d9d9d9;
  .lc-tabs {
    &-nav {
      display: flex;
      color: $color;
      border-bottom: 1px solid $border-color;
      position: relative;
      &-item {
        padding: 8px 0;
        margin: 0 16px;
        cursor: pointer;
        &:first-child {
        margin-left: 0;
      }
        &.selected {
        color: $blue;
      }
      }
      &-indicator {
        position: absolute;
        height: 3px;
         background: $blue;
        left: 0;
        bottom: -1px;
        width: 100px;
        transition: all 1s; // 添加动画
      }
    }
    &-content {
      padding: 8px 0;
    }
  }
</style>
